package org.example;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Iterator;

public class ServerChar extends JFrame {
    private static final int PORT = 8888;
    JTextArea jta = new JTextArea();
    JScrollPane jsp = new JScrollPane(jta);
    private JPanel south = new JPanel(); //面板
    private JLabel jb = new JLabel();
    private JButton stopBtn = new JButton("停止服务器");

    private boolean isStart = false;//服务器是否启动

    private ServerSocket serverSocket = null;

    private ArrayList<ClientConn> clientConn = new ArrayList<>();
    private int peopleOnline = 0;

    public ServerChar(){
        this.setTitle("服务端");
        this.add(jsp, BorderLayout.CENTER);
        jta.setEditable(false); //不能输入
        south.add(jb);
        jb.setText("聊天室在线人数: "+peopleOnline+"   ");
        south.add(stopBtn);
        this.add(south,BorderLayout.SOUTH);

        stopBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                isStart = false;
                try {
                    if (serverSocket != null){
                        serverSocket.close();
                        isStart = false;
                    }
                } catch (IOException ex) {
                    ex.printStackTrace();
                }finally {
                    System.exit(0);
                }
            }
        });

        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                isStart = false;
                try {
                    if (serverSocket != null){
                        serverSocket.close();
                        isStart = false;
                    }
                } catch (IOException ex) {
                    ex.printStackTrace();
                }finally {
                    System.exit(0);
                }
            }
        });
        this.setBounds(200,100,500,500);
        this.setVisible(true);
        startServer();
    }

    //服务器启动的方法
    public void startServer()  {
        try{
            try {
                serverSocket = new ServerSocket(PORT);
                isStart = true;
                jta.append("服务器已启动,等待客户端连接..."+System.lineSeparator());
            } catch (IOException e) {
                e.printStackTrace();
            }
            while(isStart){
                Socket socket = serverSocket.accept();
                clientConn.add(new ClientConn(socket));
                jta.append("客户端"+"["+socket.getInetAddress()+"-"+socket.getPort()+"]"+"加入聊天室"+System.lineSeparator());
                jb.setText("聊天室在线人数: "+(++peopleOnline)+"   ");
            }
        }catch (SocketException e){
            System.out.println("服务器中断");
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    //这个对象属于服务器端的连接对象
    class ClientConn implements Runnable{
        Socket socket = null;
        //构造器 传入socket
        public ClientConn(Socket socket){
            this.socket=socket;
            (new Thread(this)).start();
        }

        @Override//同时接收客户端信息
        public void run() {
            String name = socket.getInetAddress()+"-"+socket.getPort();
            try {
                DataInputStream dis = new DataInputStream(socket.getInputStream());
                while (isStart){
                    //读过来
                    String str = dis.readUTF();
                    if (str.startsWith("##")){
                        name = str.substring("##".length(),str.length());
                        jta.append("客户端"+"["+socket.getInetAddress()+"-"+socket.getPort()+"]"+"将名称设置为"+"["+name+"]"+System.lineSeparator());
                        Iterator<ClientConn> it = clientConn.iterator();
                        while(it.hasNext()) {
                            ClientConn o = it.next();
                            o.send(name+"加入了聊天室"+System.lineSeparator());
                        }
                    }else{
                        jta.append("["+name+"]"+"说:"+str+System.lineSeparator());
                        //发过去
                        String strSend = "["+name+"]"+"说:"+str+System.lineSeparator();
                        //要遍历所有的客户端来发送 遍历ccList 调用send方法
                        Iterator<ClientConn> it = clientConn.iterator();
                        while(it.hasNext()) {
                            ClientConn o = it.next();
                            o.send(strSend);
                        }
                    }
                }
            } catch (SocketException e){
                jta.append("客户端"+"["+name+"]"+"下线了"+System.lineSeparator());
                Iterator<ClientConn> it = clientConn.iterator();
                while(it.hasNext()) {
                    ClientConn o = it.next();
                    o.send(name+"退出了聊天室"+System.lineSeparator());
                }
                jb.setText("聊天室在线人数: "+(--peopleOnline)+"   ");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        //对每个连接发送信息的方法
        public void send(String str){
            try {
                DataOutputStream dos = new DataOutputStream(this.socket.getOutputStream());
                dos.writeUTF(str);
                dos.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        new ServerChar();
    }

}